import { upFixed, subtract } from "@/utils";
import {
  differenceInDays,
  differenceInCalendarMonths,
  isSameWeek,
} from "date-fns";

// 计算y轴刻度值
export function yAxisNumber(list) {
  const res = [];
  list = list.filter((i) => i != null);
  const min = Math.min.apply(null, list);
  const max = Math.max.apply(null, list);
  const n = Number(upFixed((max - min) / 4, 2));
  // const n = Math.ceil((max - min)/4) // todo y轴颗粒度
  if (!n) {
    return [-1, 1, 1];
  }
  res[2] = n;
  res[0] = Number((min - n / 2).toFixed(2));
  // res[0] = Number((min - n/2).toFixed(0)) // todo y轴颗粒度
  res[1] = res[0] + n * 5;
  return res;
}

// echarts 归0处理
export function xReturnZero(
  data1,
  data2,
  op,
  op1,
  baseline_i,
  end_i,
  isIndexList,
  warehouseAdjustmentCycle,
  reals
) {
  const all_list_obj1 = []; // 处理y轴间距
  let baseline_val1_netWorth; // 动态净值 （记录组合高点的动态净值）
  Object.keys(data1).forEach((key, data1_i) => {
    // if(Object.keys(op.legend[0].selected).length==0 || op.legend[0].selected[key] || op.legend[0].selected[key]==undefined) { // 之前优化算法，图例未选中不参与计算
    const real = reals.find((item) => item.key == key);
    const list = data1[key];
    const list1 = data2[key];
    if (list.length - 1 >= baseline_i) {
      let baseline_val = data1[key][baseline_i];
      let baseline_val__real = 0;
      if (real && real.key == key) {
        // 实例不同于其他曲线的基准值计算
        if (baseline_i < real.base_real_i) {
          baseline_val__real =
            op.series.find((item) => item.name == real.mainKey).data[
              real.base_real_i
            ] - list[real.base_real_i];
        }
      }
      if (baseline_val == null && real && real.key != key) {
        // 如果后面连续30个值有不为null，则为基准值  解决日周月混合曲线归0问题
        for (let index = 1; index < 32; index++) {
          const val = data1[key][baseline_i + index];
          if (val) {
            baseline_val = val;
            break;
          }
        }
      }
      let baseline_val1; // 风险基准--当前时间段区域收益最大值
      let n = 0;
      const data = list.map((item, i) => {
        if (item != null) {
          if (baseline_val != null) {
            if (warehouseAdjustmentCycle == 1) {
              n = Number(
                subtract(item, baseline_val) + baseline_val__real
              ).toFixed(2);
            } else {
              if (isIndexList.indexOf(key) != -1 || (real && real.key == key)) {
                n = Number(
                  subtract(item, baseline_val) + baseline_val__real
                ).toFixed(2);
              } else {
                // n = (Number(subtract(item, baseline_val)/api_data[baseline_i].item[0].netWorth)).toFixed(2)
                n = Number(subtract(item, baseline_val)).toFixed(2);
              }
            }
          } else {
            if (real && real.key != key) {
              n = item;
            } else {
              n = Number(Number(item) + baseline_val__real).toFixed(2);
            }
          }
        } else {
          n = null;
        }
        if (
          baseline_i <= i &&
          i <= end_i &&
          (Object.keys(op.legend[0].selected).length == 0 ||
            op.legend[0].selected[key] ||
            op.legend[0].selected[key] == undefined)
        ) {
          all_list_obj1.push(n);
        }
        if (baseline_i <= i && i <= end_i && n != null) {
          // 得风险区间基准值（如果当前值大于记录值且i处于区间内，则替换‘风险基准’值）
          if (baseline_val1 == undefined) {
            baseline_val1 = n;
            // baseline_val1_netWorth = api_data[i].item.find(item => item.webKey==key).netWorth
            if (data1_i == 0) baseline_val1_netWorth = n / 100 + 1;
          }
          if (n == null) {
            list1[i] = null;
          } else if (Number(n) < Number(baseline_val1)) {
            if (isIndexList.indexOf(key) == -1) {
              if (warehouseAdjustmentCycle == 1 || (real && real.key == key)) {
                // 单利和实盘
                list1[i] = (n - baseline_val1).toFixed(2);
              } else {
                list1[i] = (
                  (n - baseline_val1) /
                  baseline_val1_netWorth
                ).toFixed(2); // 组成曲线都按拟合曲线的起始点计算
              }
            } else {
              list1[i] = (
                ((n - baseline_val1) / (Number(baseline_val1) + 100)) *
                100
              ).toFixed(2);
            }
          } else {
            baseline_val1 = n;
            // baseline_val1_netWorth = api_data[i].item.find(item => item.webKey==key).netWorth
            if (data1_i == 0) baseline_val1_netWorth = n / 100 + 1;
            list1[i] = 0;
          }
        }
        return n;
      });
      op.series[data1_i].data = data;
      op1.series[data1_i].data = list1;
    }
    // }
  });
  return { op, op1, all_list_obj1 };
}

export function xReturnZero2(
  data1,
  data2,
  op,
  op1,
  baseline_i,
  end_i,
  isIndexList,
  realKey,
  base_real_i,
  mainKey,
  warehouseAdjustmentCycle,
  relativeIncome_coeff = 1
) {
  const all_list_obj1 = []; // 处理y轴间距
  Object.keys(data1).forEach((key, data1_i) => {
    // if(Object.keys(op.legend[0].selected).length==0 || op.legend[0].selected[key] || op.legend[0].selected[key]==undefined) { // 之前优化算法，图例未选中不参与计算
    const list = data1[key];
    const list1 = data2[key];
    if (list.length - 1 >= baseline_i) {
      let baseline_val = data1[key][baseline_i];
      let baseline_val__real = 0;
      if (realKey == key) {
        // 实例不同于其他曲线的基准值计算
        if (baseline_i < base_real_i) {
          baseline_val__real =
            op.series.find((item) => item.name == mainKey).data[base_real_i] -
            list[base_real_i];
        }
      }
      if (baseline_val == null && realKey != key) {
        // 如果后面连续30个值有不为null，则为基准值  解决日周月混合曲线归0问题
        for (let index = 1; index < 32; index++) {
          const val = data1[key][baseline_i + index];
          if (val) {
            baseline_val = val;
            break;
          }
        }
      }
      let baseline_val1; // 风险基准--当前时间段区域收益最大值
      let baseline_val1_netWorth;
      let n = 0;
      const data = list.map((item, i) => {
        if (item != null) {
          if (baseline_val != null) {
            if (warehouseAdjustmentCycle == 1) {
              n = (
                Number(subtract(item, baseline_val) + baseline_val__real) /
                relativeIncome_coeff
              ).toFixed(2);
            } else {
              if (isIndexList.indexOf(key) != -1 || realKey == key) {
                n = Number(
                  subtract(item, baseline_val) + baseline_val__real
                ).toFixed(2);
              } else {
                // n = (Number((subtract(item, baseline_val)+baseline_val__real)/api_data[baseline_i].item[0].netWorth)).toFixed(2)
                n = Number(
                  subtract(item, baseline_val) + baseline_val__real
                ).toFixed(2);
              }
            }
          } else {
            if (realKey != key) {
              n = item;
            } else {
              n = Number(Number(item) + baseline_val__real).toFixed(2);
            }
          }
        } else {
          n = null;
        }
        if (
          baseline_i <= i &&
          i <= end_i &&
          (Object.keys(op.legend[0].selected).length == 0 ||
            op.legend[0].selected[key] ||
            op.legend[0].selected[key] == undefined)
        ) {
          all_list_obj1.push(n);
        }
        if (baseline_i <= i && i <= end_i && n != null) {
          // 得风险区间基准值（如果当前值大于记录值且i处于区间内，则替换‘风险基准’值）
          if (baseline_val1 == undefined) {
            baseline_val1 = n;
            // baseline_val1_netWorth = api_data[i].item.find(item => item.webKey==key).netWorth
            if (data1_i == 0) baseline_val1_netWorth = n / 100 + 1;
          }
          if (n == null) {
            list1[i] = null;
          } else if (Number(n) < Number(baseline_val1)) {
            if (isIndexList.indexOf(key) == -1) {
              if (warehouseAdjustmentCycle == 1 || realKey == key) {
                // 单利和实盘
                list1[i] = (n - baseline_val1).toFixed(2);
              } else {
                list1[i] = (
                  (n - baseline_val1) /
                  baseline_val1_netWorth
                ).toFixed(2);
              }
            } else {
              list1[i] = (
                ((n - baseline_val1) / (Number(baseline_val1) + 100)) *
                100
              ).toFixed(2);
            }
          } else {
            baseline_val1 = n;
            // baseline_val1_netWorth = api_data[i].item.find(item => item.webKey==key).netWorth
            if (data1_i == 0) baseline_val1_netWorth = n / 100 + 1;
            list1[i] = 0;
          }
        }
        return n;
      });
      op.series[data1_i].data = data;
      op1.series[data1_i].data = list1;
    }
    // }
  });
  return { op, op1, all_list_obj1 };
}

export function xReturnZeroFristPage(
  data1,
  data2,
  op,
  op1,
  baseline_i,
  end_i,
  isIndexList,
  realKey,
  base_real_i,
  mainKey
) {
  const all_list_obj1 = []; // 处理y轴间距
  Object.keys(data1).forEach((key, i) => {
    // if(Object.keys(op.legend[0].selected).length==0 || op.legend[0].selected[key] || op.legend[0].selected[key]==undefined) { // 之前优化算法，图例未选中不参与计算
    const list = data1[key];
    const list1 = data2[key];
    if (list.length - 1 >= baseline_i) {
      let baseline_val = data1[key][baseline_i];
      let baseline_val__real = 0;
      if (realKey == key) {
        // 实例不同于其他曲线的基准值计算
        if (baseline_i < base_real_i) {
          baseline_val__real =
            op.series.find((item) => item.name == mainKey).data[base_real_i] -
            list[base_real_i];
        }
      }
      if (baseline_val == null && realKey != key) {
        // 如果后面连续30个值有不为null，则为基准值  解决日周月混合曲线归0问题
        for (let index = 1; index < 32; index++) {
          const val = data1[key][baseline_i + index];
          if (val) {
            baseline_val = val;
            break;
          }
        }
      }
      let baseline_val1; // 风险基准--当前时间段区域收益最大值
      let n = 0;
      const data = list.map((item, i) => {
        if (item != null) {
          if (baseline_val != null) {
            n = Number(
              subtract(item, baseline_val) + baseline_val__real
            ).toFixed(2);
          } else {
            if (realKey != key) {
              n = item;
            } else {
              n = Number(Number(item) + baseline_val__real).toFixed(2);
            }
          }
        } else {
          n = null;
        }
        if (
          baseline_i <= i &&
          i <= end_i &&
          (Object.keys(op.legend[0].selected).length == 0 ||
            op.legend[0].selected[key] ||
            op.legend[0].selected[key] == undefined)
        ) {
          all_list_obj1.push(n);
        }
        if (baseline_i <= i && i <= end_i && n != null) {
          // 得风险区间基准值（如果当前值大于记录值且i处于区间内，则替换‘风险基准’值）
          if (baseline_val1 == undefined) baseline_val1 = n;
          if (n == null) {
            list1[i] = null;
          } else if (Number(n) < Number(baseline_val1)) {
            if (isIndexList.indexOf(key) == -1) {
              list1[i] = (n - baseline_val1).toFixed(2); // pnl区间收益版
            } else {
              list1[i] = (
                ((n - baseline_val1) / (Number(baseline_val1) + 100)) *
                100
              ).toFixed(2);
            }
          } else {
            baseline_val1 = n;
            list1[i] = 0;
          }
        }
        return n;
      });
      op.series[i].data = data;
      op1.series[i].data = list1;
    }
    // }
  });
  return { op, op1, all_list_obj1 };
}

/**
 * 随机数函数
 * @param {Number} n
 * @returns
 */
export function randomStr(n) {
  const data = [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "A",
    "B",
    "C",
    "D",
    "E",
    "F",
    "G",
    "H",
    "I",
    "J",
    "K",
    "L",
    "M",
    "N",
    "O",
    "P",
    "Q",
    "R",
    "S",
    "T",
    "U",
    "V",
    "W",
    "X",
    "Y",
    "Z",
    "a",
    "b",
    "c",
    "d",
    "e",
    "f",
    "g",
    "h",
    "i",
    "j",
    "k",
    "l",
    "m",
    "n",
    "o",
    "p",
    "q",
    "r",
    "s",
    "t",
    "u",
    "v",
    "w",
    "x",
    "y",
    "z",
  ];

  let result = "";
  for (let i = 0; i < n; i++) {
    const r = Math.floor(Math.random() * 62); // 取得0-62间的随机数，目的是以此当下标取数组data里的值！
    result += data[r]; // 输出n次随机数的同时，让rrr加n次，就是n位的随机字符串了。
  }
  return result;
}

/**
 * 随机数函数
 * @param {Number} n
 * @returns
 */
export function randomNum(n) {
  const data = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];

  let result = "";
  for (let i = 0; i < n; i++) {
    const r = Math.floor(Math.random() * 9); // 取得0-62间的随机数，目的是以此当下标取数组data里的值！
    result += data[r]; // 输出n次随机数的同时，让rrr加n次，就是n位的随机字符串了。
  }
  return Number(result);
}

/**
 * 根据日期判断数据是日，周，月频数据
 * @param {Array} dates 日期数组
 * @returns 1.日，2.周，3.月
 */
export function chartDateFreq(dates) {
  let _dates = JSON.parse(JSON.stringify(dates));
  if (_dates.length > 100) {
    // 只需平均截取前100位样品数据
    const dates_line = Math.floor(_dates.length / 4);
    // _dates = [
    //   ..._dates.slice(0, 26),
    //   ..._dates.slice(dates_line+1, dates_line*2+1),
    //   ..._dates.slice(dates_line*2+1, dates_line*3+1),
    //   ..._dates.slice(dates_line*3+1, dates_line*4+1)
    // ]
    _dates = [
      ..._dates.slice(0, 25),
      ..._dates.slice(dates_line, dates_line + 25),
      ..._dates.slice(dates_line * 2, dates_line * 2 + 25),
      ..._dates.slice(dates_line * 3, dates_line * 3 + 25),
    ];
  }
  const nums = []; // 每条数据的时间间隔
  _dates.map((item, i) => {
    if (i < _dates.length - 1) {
      nums.push(differenceInDays(_dates[i + 1], item));
    }
  });
  const l_day = nums.filter((e) => e < 3).length;
  const l_week = nums.filter((e) => e > 3 && e < 8).length;
  const l_month = nums.filter((e) => e > 7).length;
  const max = Math.max(l_day, l_week, l_month);
  if (max == l_day) return 1;
  if (max == l_week) return 2;
  if (max == l_month) return 3;
}

/**
 * 根据净值条数判断数据是日，周，月频数据 （净值中间填充了null）
 * @param {Array} list 净值/pnl数组
 * @param {Array} dates x轴时间数组
 * @returns 1.日，7.周，30.月
 */
export function chartDateFreqOnValue(list, dates) {
  let _list = JSON.parse(JSON.stringify(list));
  // let _list_realL = _list.length
  // let realL = dates.length - _list_realL
  if (_list.length > 100) {
    // 只需平均截取100位样品数据
    const val_line = Math.floor(_list.length / 4);
    _list = [
      ..._list.slice(0, 26),
      ..._list.slice(val_line + 1, val_line * 2 + 1),
      ..._list.slice(val_line * 2 + 1, val_line * 3 + 1),
      ..._list.slice(val_line * 3 + 1, val_line * 4 + 1),
    ];
  }
  let nums_notNull = 0; // null的个数
  _list.forEach((n) => {
    if (n != null) nums_notNull++;
  });
  const res = nums_notNull / _list.length;
  if (res > 0.3) return 1;
  if (res > 0.07 && res <= 0.3) return 7;
  if (res <= 0.07) return 30;
}

// 历史收益走势图--计算周频
export function getWeekData(
  dates,
  objs,
  objs1,
  isIndexList,
  warehouseAdjustmentCycle,
  reals
) {
  const res_dates = [];
  const res_objs = {};
  const res_objs1 = {};
  Object.keys(objs).map((key) => {
    res_objs[key] = [];
    res_objs1[key] = [];
  });
  reals = reals.map((r) => {
    return {
      ...r,
      base_real_i: null,
    };
  });
  const _dates = JSON.parse(JSON.stringify(dates));
  const base_num1_key = {};
  let zuhe_base_moveNetworth;
  const base_num = {};
  _dates.map((date, i) => {
    if (i < _dates.length - 1 && i != 0) {
      if (!isSameWeek(date, _dates[i + 1])) {
        res_dates.push(date);
        let one_res_key = "";
        Object.keys(res_objs).map((res_key, res_key_i) => {
          const real_i = reals.findIndex((r) => r.key == res_key);
          let real;
          if (real_i != -1) real = reals[real_i];
          if (res_key_i == 0) one_res_key = res_key;
          if (real && real.base_real_i == null && objs[res_key][i] != null) {
            real.base_real_i = res_dates.length - 1;
            reals[real_i].base_real_i = real.base_real_i;
            reals[real_i].base_real = objs[res_key][i] - objs[real.mainKey][i];
          }
          // 收益数据
          if (base_num[res_key] == undefined && !real) {
            // base_num = res_objs[res_key][0]!=undefined ? res_objs[res_key][0] : objs[res_key][i]
            base_num[res_key] =
              res_objs[res_key][0] != undefined
                ? base_num[res_key]
                : objs[res_key][i];
          }
          if (real && real.base_real_i != null) {
            base_num[res_key] = real.base_real;
          }
          if (objs[res_key][i] != null) {
            res_objs[res_key].push(
              (objs[res_key][i] - base_num[res_key]).toFixed(2)
            ); // '-base_num[res_key]' 归0
          } else {
            let num = 1;
            while (
              isSameWeek(date, _dates[i - num]) &&
              res_objs[res_key][res_objs[one_res_key].length-1] == undefined
            ) {
              if (objs[res_key][i - num] != null) {
                res_objs[res_key].push(
                  (objs[res_key][i - num] - base_num[res_key]).toFixed(2)
                );
              }
              num++;
            }
            if (res_objs[res_key][res_objs[one_res_key].length-1] == undefined) {
              res_objs[res_key].push(null);
            }
          }
          // 回撤数据
          const incomeVal = res_objs[res_key].slice(-1)[0];
          if (base_num1_key[res_key] == undefined) {
            base_num1_key[res_key] = incomeVal;
            if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
          }
          const base_num1 = base_num1_key[res_key];
          if (incomeVal == null) {
            res_objs1[res_key].push(null);
          } else if (Number(incomeVal) < Number(base_num1)) {
            let num = null;
            if (isIndexList.indexOf(res_key) == -1) {
              if (warehouseAdjustmentCycle == 1 || real) {
                num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
              } else {
                num = (
                  (incomeVal - base_num1) /
                  zuhe_base_moveNetworth
                ).toFixed(2);
              }
            } else {
              num = (
                ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
                100
              ).toFixed(2);
            }
            res_objs1[res_key].push(num);
          } else {
            base_num1_key[res_key] = incomeVal;
            if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
            res_objs1[res_key].push(0);
          }
        });
      }
    } else {
      // 处理最后一天
      res_dates.push(date);
      Object.keys(res_objs).map((res_key, res_key_i) => {
        const real_i = reals.findIndex((r) => r.key == res_key);
        let real;
        if (real_i != -1) real = reals[real_i];
        if (!base_num[res_key]) {
          base_num[res_key] =
            res_objs[res_key][0] != undefined
              ? res_objs[res_key][0]
              : objs[res_key][i];
        }
        if (objs[res_key][i] != null) {
          res_objs[res_key].push(
            (objs[res_key][i] - base_num[res_key]).toFixed(2)
          ); // '-base_num[res_key]' 归0
        } else {
          res_objs[res_key].push(null);
        }
        // 回撤数据
        const incomeVal = res_objs[res_key].slice(-1)[0];
        if (base_num1_key[res_key] == undefined) {
          base_num1_key[res_key] = incomeVal;
          if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
        }
        let base_num1 = base_num1_key[res_key];
        if (!base_num1_key[res_key]) {
          base_num1 =
            base_num1_key[res_key] != undefined
              ? base_num1_key[res_key]
              : incomeVal;
        }
        if (incomeVal == null) {
          res_objs1[res_key].push(null);
        } else if (Number(incomeVal) < Number(base_num1)) {
          let num = null;
          if (isIndexList.indexOf(res_key) == -1) {
            if (warehouseAdjustmentCycle == 1 || real) {
              num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
            } else {
              num = ((incomeVal - base_num1) / zuhe_base_moveNetworth).toFixed(
                2
              );
            }
          } else {
            num = (
              ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
              100
            ).toFixed(2);
          }
          res_objs1[res_key].push(num);
        } else {
          base_num1_key[res_key] = incomeVal;
          if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
          res_objs1[res_key].push(0);
        }
      });
    }
  });
  return [res_dates, res_objs, res_objs1, reals];
}

// 历史收益走势图--计算月频
export function getMonthData(
  dates,
  objs,
  objs1,
  isIndexList,
  warehouseAdjustmentCycle,
  reals
) {
  const res_dates = [];
  const res_objs = {};
  const res_objs1 = {};
  Object.keys(objs).map((key) => {
    res_objs[key] = [];
    res_objs1[key] = [];
  });
  reals = reals.map((r) => {
    return {
      ...r,
      base_real_i: null,
    };
  });
  const _dates = JSON.parse(JSON.stringify(dates));
  const base_num1_key = {};
  let zuhe_base_moveNetworth;
  const base_num = {};
  _dates.map((date, i) => {
    if (i < _dates.length - 1 && i != 0) {
      const dateComs = date.split("-");
      const next_dateComs = _dates[i + 1].split("-");
      if (
        !(
          dateComs[0] == next_dateComs[0] &&
          Number(dateComs[1]) == Number(next_dateComs[1])
        )
      ) {
        res_dates.push(date);
        let one_res_key = "";
        Object.keys(res_objs).map((res_key, res_key_i) => {
          const real_i = reals.findIndex((r) => r.key == res_key);
          let real;
          if (real_i != -1) real = reals[real_i];
          if (res_key_i == 0) one_res_key = res_key;
          if (real && real.base_real_i == null && objs[res_key][i] != null) {
            // todo objs[res_key][i]!=null 且不是起始处 需往上追溯收益率
            real.base_real_i = res_dates.length - 1;
            reals[real_i].base_real_i = real.base_real_i;
            reals[real_i].base_real = objs[res_key][i] - objs[real.mainKey][i];
          }
          // 收益数据
          if (base_num[res_key] == undefined && !real) {
            base_num[res_key] =
              res_objs[res_key][0] != undefined
                ? res_objs[res_key][0]
                : objs[res_key][i];
          }
          if (real && real.base_real_i != null) {
            base_num[res_key] = real.base_real;
          }
          if (objs[res_key][i] != null) {
            res_objs[res_key].push(
              (objs[res_key][i] - base_num[res_key]).toFixed(2)
            ); // '-base_num[res_key]' 归0
          } else {
            let num = 1;
            while (
              dateComs == _dates[i - num].split("-")[0] &&
              res_objs[res_key][res_objs[one_res_key].length-1] == undefined
            ) {
              if (objs[res_key][i - num] != null) {
                res_objs[res_key].push(
                  (objs[res_key][i - num] - base_num[res_key]).toFixed(2)
                );
              }
              num++;
            }
            if (res_objs[res_key][res_objs[one_res_key].length-1] == undefined) {
              res_objs[res_key].push(null);
            }
          }
          // 回撤数据
          const incomeVal = res_objs[res_key].slice(-1)[0];
          if (base_num1_key[res_key] == undefined) {
            base_num1_key[res_key] = incomeVal;
            if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
          }
          const base_num1 = base_num1_key[res_key];
          if (incomeVal == null) {
            res_objs1[res_key].push(null);
          } else if (Number(incomeVal) < Number(base_num1)) {
            let num = null;
            if (isIndexList.indexOf(res_key) == -1) {
              if (warehouseAdjustmentCycle == 1 || real) {
                num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
              } else {
                num = (
                  (incomeVal - base_num1) /
                  zuhe_base_moveNetworth
                ).toFixed(2);
              }
            } else {
              num = (
                ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
                100
              ).toFixed(2);
            }
            res_objs1[res_key].push(num);
          } else {
            base_num1_key[res_key] = incomeVal;
            if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
            res_objs1[res_key].push(0);
          }
        });
      }
    } else {
      // 处理最后一天
      res_dates.push(date);
      Object.keys(res_objs).map((res_key, res_key_i) => {
        const real_i = reals.findIndex((r) => r.key == res_key);
        let real;
        if (real_i != -1) real = reals[real_i];
        // 收益数据
        if (!base_num[res_key]) {
          base_num[res_key] =
            res_objs[res_key][0] != undefined
              ? res_objs[res_key][0]
              : objs[res_key][i];
        }
        if (objs[res_key][i] != null) {
          res_objs[res_key].push(
            (objs[res_key][i] - base_num[res_key]).toFixed(2)
          ); // '-base_num[res_key]' 归0
        } else {
          res_objs[res_key].push(null);
        }
        // 回撤数据
        const incomeVal = res_objs[res_key].slice(-1)[0];
        if (base_num1_key[res_key] == undefined) {
          base_num1_key[res_key] = incomeVal;
          if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
        }
        let base_num1 = base_num1_key[res_key];
        if (!base_num1_key[res_key]) {
          base_num1 =
            base_num1_key[res_key] != undefined
              ? base_num1_key[res_key]
              : incomeVal;
        }
        if (incomeVal == null) {
          res_objs1[res_key].push(null);
        } else if (Number(incomeVal) < Number(base_num1)) {
          let num = null;
          if (isIndexList.indexOf(res_key) == -1) {
            if (warehouseAdjustmentCycle == 1 || real) {
              num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
            } else {
              num = ((incomeVal - base_num1) / zuhe_base_moveNetworth).toFixed(
                2
              );
            }
          } else {
            num = (
              ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
              100
            ).toFixed(2);
          }
          res_objs1[res_key].push(num);
        } else {
          base_num1_key[res_key] = incomeVal;
          if (res_key_i == 0) zuhe_base_moveNetworth = incomeVal / 100 + 1;
          res_objs1[res_key].push(0);
        }
      });
    }
  });
  return [res_dates, res_objs, res_objs1, reals];
}

// 历史收益走势图--计算周频
export function getWeekData2(
  dates,
  objs,
  objs1,
  isIndexList,
  realKey,
  base_real_i,
  mainKey
) {
  const res_dates = [];
  const res_objs = {};
  const res_objs1 = {};
  let res_real_i; // 数组长度改变，实例对齐点位置也跟着改变
  Object.keys(objs).map((key) => {
    res_objs[key] = [];
    res_objs1[key] = [];
  });
  const _dates = JSON.parse(JSON.stringify(dates));
  let base_real;
  const base_num = {};
  const base_num1_key = {};
  _dates.map((date, i) => {
    if (i < _dates.length - 1 && i != 0) {
      if (!isSameWeek(date, _dates[i + 1])) {
        res_dates.push(date);
        let one_res_key = "";
        Object.keys(res_objs).map((res_key, res_key_i) => {
          if (res_key_i == 0) one_res_key = res_key;
          if (
            base_real == undefined &&
            res_key == realKey &&
            i >= base_real_i
          ) {
            res_real_i = res_dates.length - 1;
            base_real = objs[res_key][i] - objs[mainKey][i];
          }
          // 收益数据
          if (!base_num[res_key] && res_key != realKey) {
            base_num[res_key] =
              res_objs[res_key][0] != undefined
                ? res_objs[res_key][0]
                : objs[res_key][i];
          }
          if (res_key == realKey && base_real != undefined) {
            base_num[res_key] = base_real;
          }
          if (objs[res_key][i] != null) {
            res_objs[res_key].push(
              (objs[res_key][i] - base_num[res_key]).toFixed(2)
            ); // '-base_num[res_key]' 归0
          } else {
            let num = 1;
            while (
              isSameWeek(date, _dates[i - num]) &&
              res_objs[res_key][res_objs[one_res_key].length-1] == undefined
            ) {
              if (objs[res_key][i - num] != null) {
                res_objs[res_key].push(
                  (objs[res_key][i - num] - base_num[res_key]).toFixed(2)
                );
              }
              num++;
            }
            if (res_objs[res_key][res_objs[one_res_key].length-1] == undefined) {
              res_objs[res_key].push(null);
            }
          }
          // 回撤数据
          const incomeVal = res_objs[res_key].slice(-1)[0];
          if (base_num1_key[res_key] == undefined) {
            base_num1_key[res_key] = incomeVal;
          }
          const base_num1 = base_num1_key[res_key];
          if (incomeVal == null) {
            res_objs1[res_key].push(null);
          } else if (Number(incomeVal) < Number(base_num1)) {
            let num = null;
            if (isIndexList.indexOf(res_key) == -1) {
              num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
            } else {
              num = (
                ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
                100
              ).toFixed(2);
            }
            res_objs1[res_key].push(num);
          } else {
            base_num1_key[res_key] = incomeVal;
            res_objs1[res_key].push(0);
          }
        });
      }
    } else {
      // 处理最后一天
      res_dates.push(date);
      Object.keys(res_objs).map((res_key) => {
        if (!base_num[res_key]) {
          base_num[res_key] =
            res_objs[res_key][0] != undefined
              ? res_objs[res_key][0]
              : objs[res_key][i];
        }

        if (objs[res_key][i] != null) {
          res_objs[res_key].push(
            (objs[res_key][i] - base_num[res_key]).toFixed(2)
          ); // '-base_num[res_key]' 归0
        } else {
          res_objs[res_key].push(null);
        }
        // 回撤数据
        const incomeVal = res_objs[res_key].slice(-1)[0];
        if (base_num1_key[res_key] == undefined) {
          base_num1_key[res_key] = incomeVal;
        }
        let base_num1 = base_num1_key[res_key];
        if (!base_num1_key[res_key]) {
          base_num1 =
            base_num1_key[res_key] != undefined
              ? base_num1_key[res_key]
              : incomeVal;
        }

        if (incomeVal == null) {
          res_objs1[res_key].push(null);
        } else if (Number(incomeVal) < Number(base_num1)) {
          let num = null;
          if (isIndexList.indexOf(res_key) == -1) {
            num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
          } else {
            num = (
              ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
              100
            ).toFixed(2);
          }
          res_objs1[res_key].push(num);
        } else {
          base_num1_key[res_key] = incomeVal;
          res_objs1[res_key].push(0);
        }
      });
    }
  });
  return [res_dates, res_objs, res_objs1, res_real_i];
}

// 历史收益走势图--计算月频
export function getMonthData2(
  dates,
  objs,
  objs1,
  isIndexList,
  realKey,
  base_real_i,
  mainKey
) {
  const res_dates = [];
  const res_objs = {};
  const res_objs1 = {};
  let res_real_i;
  Object.keys(objs).map((key) => {
    res_objs[key] = [];
    res_objs1[key] = [];
  });
  const _dates = JSON.parse(JSON.stringify(dates));
  let base_real;
  const base_num = {};
  const base_num1_key = {};
  _dates.map((date, i) => {
    if (i < _dates.length - 1 && i != 0) {
      const dateComs = date.split("-");
      const next_dateComs = _dates[i + 1].split("-");
      if (
        !(
          dateComs[0] == next_dateComs[0] &&
          Number(dateComs[1]) == Number(next_dateComs[1])
        )
      ) {
        res_dates.push(date);
        let one_res_key = "";
        Object.keys(res_objs).map((res_key, res_key_i) => {
          if (res_key_i == 0) one_res_key = res_key;
          if (
            base_real == undefined &&
            res_key == realKey &&
            i >= base_real_i
          ) {
            res_real_i = res_dates.length - 1;
            base_real = objs[res_key][i] - objs[mainKey][i];
          }
          // 收益数据
          if (!base_num[res_key]) {
            base_num[res_key] =
              res_objs[res_key][0] != undefined
                ? res_objs[res_key][0]
                : objs[res_key][i];
          }

          if (res_key == realKey && base_real != undefined) {
            base_num[res_key] = base_real;
          }
          if (objs[res_key][i] != null) {
            res_objs[res_key].push(
              (objs[res_key][i] - base_num[res_key]).toFixed(2)
            ); // '-base_num[res_key]' 归0
          } else {
            let num = 1;
            while (
              dateComs == _dates[i - num].split("-")[0] &&
              res_objs[res_key][res_objs[one_res_key].length-1] == undefined
            ) {
              if (objs[res_key][i - num] != null) {
                res_objs[res_key].push(
                  (objs[res_key][i - num] - base_num[res_key]).toFixed(2)
                );
              }
              num++;
            }
            if (res_objs[res_key][res_objs[one_res_key].length-1] == undefined) {
              res_objs[res_key].push(null);
            }
          }
          // 回撤数据
          const incomeVal = res_objs[res_key].slice(-1)[0];
          if (base_num1_key[res_key] == undefined) {
            base_num1_key[res_key] = incomeVal;
          }
          const base_num1 = base_num1_key[res_key];
          if (incomeVal == null) {
            res_objs1[res_key].push(null);
          } else if (Number(incomeVal) < Number(base_num1)) {
            let num = null;
            if (isIndexList.indexOf(res_key) == -1) {
              num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
            } else {
              num = (
                ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
                100
              ).toFixed(2);
            }
            res_objs1[res_key].push(num);
          } else {
            base_num1_key[res_key] = incomeVal;
            res_objs1[res_key].push(0);
          }
        });
      }
    } else {
      // 处理最后一天
      res_dates.push(date);
      Object.keys(res_objs).map((res_key) => {
        // 收益数据
        if (!base_num[res_key]) {
          base_num[res_key] =
            res_objs[res_key][0] != undefined
              ? res_objs[res_key][0]
              : objs[res_key][i];
        }
        if (objs[res_key][i] != null) {
          res_objs[res_key].push(
            (objs[res_key][i] - base_num[res_key]).toFixed(2)
          ); // '-base_num[res_key]' 归0
        } else {
          res_objs[res_key].push(null);
        }
        // 回撤数据
        const incomeVal = res_objs[res_key].slice(-1)[0];
        if (base_num1_key[res_key] == undefined) {
          base_num1_key[res_key] = incomeVal;
        }
        let base_num1 = base_num1_key[res_key];
        if (!base_num1_key[res_key]) {
          base_num1 =
            base_num1_key[res_key] != undefined
              ? base_num1_key[res_key]
              : incomeVal;
        }

        if (incomeVal == null) {
          res_objs1[res_key].push(null);
        } else if (Number(incomeVal) < Number(base_num1)) {
          let num = null;
          if (isIndexList.indexOf(res_key) == -1) {
            num = (incomeVal - base_num1).toFixed(2); // pnl区间收益版
          } else {
            num = (
              ((incomeVal - base_num1) / (Number(base_num1) + 100)) *
              100
            ).toFixed(2);
          }
          res_objs1[res_key].push(num);
        } else {
          base_num1_key[res_key] = incomeVal;
          res_objs1[res_key].push(0);
        }
      });
    }
  });
  return [res_dates, res_objs, res_objs1, res_real_i];
}

/**
 *
 * @param {Object} objs 折线数据
 * @returns 每条数据的风险指标
 */
export function riskIndexCalc(objs) {
  // 第四个参数1为单利，其它为复利  第五为滑动起始时间 第六为原始数据
  const res = [];
  const objs1 = JSON.parse(JSON.stringify(objs[0]));
  const objs2 = JSON.parse(JSON.stringify(objs[1]));
  Object.keys(objs1).forEach((key, index) => {
    //  数据前后去null
    let dates = JSON.parse(JSON.stringify(objs[2]));
    let obj2 = objs2[key];
    const res_afterClearNull = listAfterClearNull(objs1[key]);
    dates = dates.slice(0, dates.length - res_afterClearNull[1]);
    obj2 = obj2.slice(0, obj2.length - res_afterClearNull[1]);
    const res_beforeClearNull = listBeforeClearNull(res_afterClearNull[0]);
    dates = dates.slice(res_beforeClearNull[1]);
    obj2 = obj2.slice(res_beforeClearNull[1]);
    const obj1 = res_beforeClearNull[0];

    let nameLegend;
    if (objs[3] != undefined) nameLegend = objs[6].find((os) => os.key == key);

    if (obj1.length) {
      if (!res[index]) {
        if (objs[3] != undefined) {
          res[index] = { name: nameLegend.name };
        } else {
          res[index] = { name: key };
        }
      }
      // 收益率
      res[index].incomeRate = obj1[obj1.length - 1];
      // 年化收益率
      if (objs[3] != undefined) {
        if (nameLegend.isIndex || nameLegend.realTag || objs[3] == 1) {
          let dm = differenceInCalendarMonths(
            objs[2][objs[2].length - 1],
            objs[2][0]
          );
          dm = dm || 1;
          res[index].annualizedIncomeRate = (
            obj1[obj1.length - 1] /
            (dm / 12)
          ).toFixed(2);
        } else {
          if (key != "111111") {
            const dd = differenceInDays(
              objs[2][objs[2].length - 1],
              objs[2][0]
            );
            let base_i__netWorth = objs[5][objs[4]].item.find(
              (el) => el.webKey == key
            ).netWorth;
            if (base_i__netWorth == null) {
              let _base_i = objs[4] + 1;
              while (base_i__netWorth == null && _base_i <= objs[5].length) {
                base_i__netWorth = objs[5][_base_i].item.find(
                  (el) => el.webKey == key
                ).netWorth;
                _base_i++;
              }
            }
            const aveDay_incomeRate =
              (1 + obj1[obj1.length - 1] / 100 / base_i__netWorth) ** (1 / dd) -
              1;
            res[index].annualizedIncomeRate = (
              ((1 + aveDay_incomeRate) ** 365 - 1) *
              100
            ).toFixed(2);
          }
        }
      } else {
        let dm = differenceInCalendarMonths(
          objs[2][objs[2].length - 1],
          objs[2][0]
        );
        dm = dm || 1;
        res[index].annualizedIncomeRate = (
          obj1[obj1.length - 1] /
          (dm / 12)
        ).toFixed(2);
      }
      // 最大回撤
      const maximumDrawdownRate = Math.min.apply(null, obj2);
      res[index].maximumDrawdownRate = maximumDrawdownRate * -1 + "%";
      // 最大回撤回补期(1)
      const startDrawdownDate_i = obj2.findIndex(
        (el) => el == maximumDrawdownRate
      );
      let drawdown_max_afterIncomeRate; // 最大回撤前的最大收益
      const drawdown_max_afterIncomeRate_date = dates[startDrawdownDate_i]; // 最大回撤前最大收益日期
      let drawdown_flat_afterIncomeRate_date; // 最大回撤后平仓日期
      // 最大不创新高天数(1)
      const notByNewHightDayList = [];
      let tag = 0; // 标记是否处于记录中
      let tag_notByNewHightDay0 = "";
      let tag_notByNewHightDay1 = "";
      // 胜率
      let winningNum = 0;
      let winningLength = obj1.length; // 记录非null的长度
      let tag_winning_val; // 用于标记胜率算法中连续存在null值时上一次存在的收益率
      // 年化波动率
      let sum = 0;
      let avg = 0;
      let valid_val1 = 0;
      for (let i = 0, j = obj1.length; i < j; i++) {
        if (obj1[i] != null) {
          sum += Number((obj1[i] - valid_val1) / 100);

          // 辅助 胜率 计算
          if (i == 0) {
            winningNum++; // 和后端算法保持一致
          } else if (!tag_winning_val) {
            if (Number(obj1[i]) > Number(obj1[i - 1])) winningNum++;
          } else {
            tag_winning_val = undefined;
            if (Number(obj1[i]) > tag_winning_val) winningNum++;
          }
          valid_val1 = obj1[i];
        } else {
          if (!tag_winning_val) {
            tag_winning_val = Number(obj1[i - 1]);
          }
          winningLength--;
        }

        // 辅助 最大回撤回补期 计算
        if (i < startDrawdownDate_i) {
          if (
            !drawdown_max_afterIncomeRate ||
            Number(obj1[i]) > Number(drawdown_max_afterIncomeRate)
          ) {
            drawdown_max_afterIncomeRate = obj1[i];
            // drawdown_max_afterIncomeRate_date = dates[i]  // 从回撤前最大收益处得 最大回撤回补期 开始时间
          }
        } else {
          if (
            !drawdown_flat_afterIncomeRate_date &&
            Number(obj1[i]) >= Number(drawdown_max_afterIncomeRate)
          ) {
            drawdown_flat_afterIncomeRate_date = dates[i];
          }
        }
        // 辅助 最大不创新高天数 计算
        let tag_notByNewHight;
        obj2[i] == null
          ? (tag_notByNewHight = (obj2[i - 1] + obj2[i + 1]) / 2)
          : (tag_notByNewHight = obj2[i]); // todo 存在前后也为null的情况
        if (Number(tag_notByNewHight) != 0) {
          // 回撤不为0则走低起始 tag_notByNewHightDay0记录此次走低的开始日期
          if (!tag && dates[i - 1]) {
            tag_notByNewHightDay0 = dates[i - 1];
            // if(key=='标普500') console.log(`%c开始日期 ${tag_notByNewHightDay0}`, 'color: green');
          }
          tag = 1;
          if (i == j - 1 && tag_notByNewHightDay0 != "") {
            // 兜底 最后还处于走低的趋势
            if (dates[i] && tag_notByNewHightDay0) {
              notByNewHightDayList.push(
                differenceInDays(dates[i], tag_notByNewHightDay0)
              );
            }
            // if(key=='标普500') console.log(`%c结束日期 ${dates[i]} ${differenceInDays(dates[i], tag_notByNewHightDay0)}`, 'color: red');
          }
        } else {
          // 回撤为0则创新高 tag_notByNewHightDay1记录此次的结束日期
          if (tag) {
            tag_notByNewHightDay1 = dates[i];
            if (tag_notByNewHightDay0 && tag_notByNewHightDay1) {
              notByNewHightDayList.push(
                differenceInDays(tag_notByNewHightDay1, tag_notByNewHightDay0)
              );
            }
            // if(key=='标普500') console.log(`%c结束日期 ${tag_notByNewHightDay1} ${differenceInDays(tag_notByNewHightDay1, tag_notByNewHightDay0)}`, 'color: red');
          }
          tag = 0;
        }
      }
      // avg = sum / l
      avg = sum / winningLength; // 处理计算波动时净值有缺失的情况
      let num = 0;
      let valid_val2 = 0;
      obj1.forEach((n, i) => {
        if (n != null) {
          num =
            num +
            ((n - valid_val2) / 100 - avg) * ((n - valid_val2) / 100 - avg);
          valid_val2 = n;
        }
      });
      // 年化波动 判断频率类型
      const datesFreq = dateFreqHandle(obj1, dates);
      const freqList = [1, 7, 30];
      const freq = chartDateFreq(datesFreq);
      const annualFluctuationsRate =
        Math.sqrt((num * (365 / freqList[freq - 1])) / (winningLength - 1)) *
        100;
      res[index].annualFluctuationsRate = annualFluctuationsRate
        ? annualFluctuationsRate.toFixed(2) + "%"
        : "--";
      // 最大回撤回补期(2)
      if (
        drawdown_max_afterIncomeRate_date &&
        drawdown_flat_afterIncomeRate_date
      ) {
        res[index].maxBackIncomDay = differenceInDays(
          drawdown_flat_afterIncomeRate_date,
          drawdown_max_afterIncomeRate_date
        );
      } else {
        res[index].maxBackIncomDay = null;
        // res[index].maxBackIncomDay = 0
      }
      // 最大不创新高天数(2)
      // res[index].maxNotByNewHightDay = notByNewHightDayList.length ? Math.max.apply(null, notByNewHightDayList) : null
      res[index].maxNotByNewHightDay = notByNewHightDayList.length
        ? Math.max.apply(null, notByNewHightDayList)
        : 0;
      // 夏普比率
      if (Number(annualFluctuationsRate) == 0 || !annualFluctuationsRate) {
        res[index].sharpeRate = "--";
      } else {
        // res[index].sharpeRate = Math.abs((res[index].annualizedIncomeRate-2) / annualFluctuationsRate).toFixed(2) // 年化收益-2 2为固收
        res[index].sharpeRate = (
          (res[index].annualizedIncomeRate - 2) /
          annualFluctuationsRate
        ).toFixed(2); // 年化收益-2 2为固收
      }
      // 卡玛比率
      if (Number(maximumDrawdownRate) == 0) {
        res[index].calmarRate = "--";
      } else {
        // res[index].calmarRate = Math.abs(res[index].annualizedIncomeRate / maximumDrawdownRate*-1).toFixed(2)
        res[index].calmarRate = (
          (res[index].annualizedIncomeRate / maximumDrawdownRate) *
          -1
        ).toFixed(2);
      }
      // 胜率
      res[index].investWinningRate =
        ((winningNum / winningLength) * 100).toFixed(2) + "%";
    } else {
      res[index] = {
        name: objs[3] != undefined ? nameLegend.name : key,
        annualFluctuationsRate: "--",
        annualizedIncomeRate: null,
        calmarRate: "--",
        sharpeRate: "--",
        incomeRate: null,
        maxBackIncomDay: "--",
        maximumDrawdownRate: "--",
        maxNotByNewHightDay: "--",
        investWinningRate: "--",
      };
    }
  });
  return res;
}

// 数据为null清除日期
function dateFreqHandle(list, dates) {
  const res = [];
  for (let i = 0, j = list.length; i < j; i++) {
    if (list[i] != null) res.push(dates[i]);
  }
  return res;
}
// 清除数组末位连续的null & 清除了多少
export function listAfterClearNull(list) {
  let num = 0;
  let res = JSON.parse(JSON.stringify(list));
  while (res.length && res[res.length - 1] == null) {
    num++;
    if (res.length == 1 && res[0] == null) {
      res = [];
    } else {
      res.pop();
    }
  }
  return [res, num];
}
// 清除数组前位连续的null
function listBeforeClearNull(list) {
  let num = 0;
  let res = JSON.parse(JSON.stringify(list));
  while (res.length && res[0] == null) {
    num++;
    if (res.length == 1 && res[0] == null) {
      res = [];
    } else {
      res.shift();
    }
  }
  return [res, num];
}
// 清除数组所有的null
// function listClearNull(list) {
//   const res = []
//   for (let i = 0, j = list.length; i < j; i++) {
//     if(list[i]!=null) res.push(list[i])
//   }
//   return res
// }

/**
 * 遍历列的所有内容，获取最宽一列的宽度
 * @param arr
 * ['[组合] 内部商品组合', '[分类] 内部商品组合分类', '名称/年份']
 */
export function getMaxLength(arr) {
  return arr.reduce((acc, item) => {
    if (item) {
      const calcLen = getTextWidth(item);
      if (acc < calcLen) {
        acc = calcLen;
      }
    }
    return acc;
  }, 0);
}

/**
 * 使用span标签包裹内容，然后计算span的宽度 width： px
 * @param valArr
 */
function getTextWidth(str) {
  let width = 0;
  const html = document.createElement("span");
  html.innerText = str;
  html.className = "getTextWidth";
  document.querySelector("body").appendChild(html);
  width = document.querySelector(".getTextWidth").offsetWidth;
  document.querySelector(".getTextWidth").remove();
  return width;
}
